/*
 * Lucas McDaniel
 * GSoC '11
 * HoneyViz
 * 
 * This simple class contains information regarding a location's name and its
 * latitude and longitude.  The functions provided allow for names to be 
 * converted to lat and long, and visa versa either for a single input or 
 * an array of inputs.  Sorting methods may be sub-optimal for various size 
 * arrays.
 */

import java.util.ArrayList;

public class LocationManager {
    
    public static ArrayList list = new ArrayList();
    
    public LocationManager()
    {}
    
    public static void reset()
    {
        list = new ArrayList();
    }
    
    public static void add(Location loc)
    {
        if (list.size()==0)
            list.add(loc);
        else
        {
            boolean found = false;
            for (int inc=0; inc<list.size(); inc++)
                if (((Location)list.get(inc)).name.compareTo(loc.name)>0)
                {
                    found = true;
                    list.add(inc, loc);
                    break;
                }
            if (!found)
                list.add(loc);
        }
    }
    
    public static double[][] getLocations(String[] names)
    {
        ArrayList lats = new ArrayList();
        ArrayList longs = new ArrayList();
        int nameVal = 0;
        int listVal = 0;
        if (names == null)
            return null;
        for (int inc=0; inc<names.length; inc++)
        {
            int curr = inc;
            for (int inc2=inc+1; inc2<names.length; inc2++)
                if (names[curr].compareTo(names[inc2])>0)
                    curr = inc2;
            if (inc != curr)
            {
                String tmp = names[inc];
                names[inc] = names[curr];
                names[curr] = tmp;
            }
        }
        while (nameVal!=names.length && listVal!=list.size())
        {
            int cmpVal = names[nameVal].compareTo(((Location)list.get(listVal)).name);
            if (cmpVal==0)
            {
                lats.add(((Location)list.get(listVal)).latitude);
                longs.add(((Location)list.get(listVal)).longitude);
                listVal++;
                nameVal++;
            }
            else if (cmpVal < 0)
                nameVal ++;
            else
                listVal ++;
        }
        double[][] rtnVal = new double[lats.size()][2];
        for (int inc=0; inc<lats.size(); inc++)
        {
            rtnVal[inc][0] = (Double)lats.get(inc);
            rtnVal[inc][1] = (Double)longs.get(inc);
        }
        return rtnVal;
    }
    
    public static double[][] getSortedLocations(String[] names)
    {
        ArrayList lats = new ArrayList();
        ArrayList longs = new ArrayList();
        double[][] unSorted = getLocations(names);
        double[][] rtnVal = new double[unSorted.length][2];
        for (int inc=0; inc<unSorted.length; inc++)
        {
            boolean found = false;
            for (int inc2=0; inc2<lats.size(); inc2++)
            {
                double cmpVal = (Double)lats.get(inc2) - unSorted[inc][0];
                if (cmpVal>0)
                {
                    lats.add(inc2, unSorted[inc][0]);
                    longs.add(inc2, unSorted[inc][1]);
                    found = true;
                    break;
                }
                else if (cmpVal == 0)
                {
                    cmpVal = (Double)longs.get(inc2) - unSorted[inc][1];
                    if (cmpVal>0)
                    {
                        lats.add(inc2, unSorted[inc][0]);
                        longs.add(inc2, unSorted[inc][1]);
                        found = true;
                        break;
                    }
                }
            }
            if (!found)
            {
                lats.add(unSorted[inc][0]);
                longs.add(unSorted[inc][1]);
            }        
        }
        for (int inc=0; inc<lats.size(); inc++)
        {
            rtnVal[inc][0] = (Double)lats.get(inc);
            rtnVal[inc][1] = (Double)longs.get(inc);
        }
        return rtnVal;
    }
    
    public static String getLocationName(DataElement DE)
    {
        return getLocationName(DE.latitude, DE.longitude);
    }
    
    public static String getLocationName(double latitude, double longitude)
    {
        for (int inc=0; inc<list.size(); inc++)
        {
            Location loc = (Location)list.get(inc);
            if (latitude == loc.latitude && longitude == loc.longitude)
                return loc.name;
        }
        return "";
    }
    
    public static String[] getLocationName(double[][] doubleArr)
    {
        String[] rtnVal = new String[doubleArr.length];
        for (int inc=0; inc<doubleArr.length; inc++)
            rtnVal[inc] = getLocationName(doubleArr[inc][0], doubleArr[inc][1]);
        return rtnVal;
    }
}
